package com.example.demo.controller;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created with IntelliJ IDEA.
 * Description: 使用注解方式实现缓存
 */
@RestController
public class RedisAnnController {

    /**
     * 存入或读取缓存
     * @Cacheable 增加/删除注解
     * value值 表示保存的包名/路径
     * key 使用 #+key 的接收数据格式
     *     如果存在多个关键字，使用 + 或者 - 连接
     *     +可以直接如下方式写，- 的格式需要改成 "#name+'-'+#sex"
     *     最后存储格式中 key 的值是路径+返回的参数，比如 spring.cache:zhangsan男（保证 key 的唯一性）
     *     value 中的数据就是返回的格式，比如：name=zhangsan|sex=男
     * 此时如果我们再次以相同的参数进行访问，由于开启了缓存，因此系统在查询到缓存之后就不会再执行该方法
     * @param name
     * @param sex
     * @return
     */
    @RequestMapping("ann-get")
    @Cacheable(value = "spring.cache", key = "#name+#sex")
    public String get(String name, String sex) {
        if(!StringUtils.hasLength(name) || !StringUtils.hasLength(sex)) {
            return null;
        }
        // 测试缓存是否已开启
        System.out.println("执行了 get 方法");
        return "name=" + name + "|sex=" + sex;
    }

    // 单个参数和多个参数对照
    @RequestMapping("ann-getname")
    @Cacheable(value = "spring.cache", key = "#name")
    public String get(String name) {
        if(!StringUtils.hasLength(name)) {
            return null;
        }
        return "name=" + name;
    }

    /**
     * 更新缓存操作
     * 每次执行都要更新缓存，即使缓存里有数据，毕竟方法就是来修改它的
     * @param name
     * @param sex
     * @return
     */
    @RequestMapping("update")
    @CachePut(value = "spring.cache", key = "#name+#sex")
    public String upate(String name, String sex) {
        if(!StringUtils.hasLength(name) || !StringUtils.hasLength(sex)) {
            return null;
        }
        System.out.println("执行了 put 方法");
        return "[name=" + name + "<->" + "sex=" + sex + "]";
    }

    /**
     * 删除缓存操作，可以没有返回值
     * 注意：这里 key 的格式必须和增加时的格式一致，上面用的+，这里也必须用+
     * @param name
     * @param sex
     */
    @RequestMapping("/del")
    @CacheEvict(value = "spring.cache", key = "#name+#sex")
    public void del(String name, String sex) {
        System.out.println("执行了缓存删除操作！");
    }
}
